﻿Imports ATS.UI.Process
Imports ATS.Business.Entities
Imports System.ComponentModel
Imports System.ServiceModel
Imports System.Collections.Specialized
Imports System.Threading
Imports System.Collections.ObjectModel

Public Class PersonWindow
    Public WithEvents oWindowList As OpenedWindowList = OpenedWindowList.GetList()
    Private WithEvents oWindow As OpenedWindowClass
    Private _upc As SubmitterUserProcess = Nothing
    Private _personDetail As Person = Nothing
    Private _personDetail_asynch As Person = Nothing
    Private _personList As ObservableCollection(Of Person) = Nothing
    Private _departmentList As List(Of String) = Nothing

    Private WithEvents _backgroundWorker_Page_Load As BackgroundWorker
    Private WithEvents _backgroundWorker As BackgroundWorker
    Private WithEvents _backgroundWorker_Save As BackgroundWorker
    Private WithEvents _backgroundWorker_CheckExisting As BackgroundWorker

#Region "Window Events"

    Private Sub PersonWindow_Closed(sender As Object, e As System.EventArgs) Handles Me.Closed
        Dim ied As IEnumerable(Of OpenedWindowClass) = From d In oWindowList Where d.WindowID = Me.Name
        oWindowList.Remove(ied.First)
        If Application.Current.Windows.Count = 1 Then
            Application.Current.Windows(0).Activate()
        End If
    End Sub

    Private Sub PersonWindow_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
        If Not _personDetail Is Nothing Then
            If _personDetail.IsDirty Then
                If _
                    MessageBox.Show("There are unsaved entries. Do you really want to exit?", "Exit", _
                                     MessageBoxButton.YesNo, MessageBoxImage.Warning) = MessageBoxResult.No Then
                    e.Cancel = True
                    _personDetail.EndEdit()
                End If
            End If
        End If
    End Sub

    Public Sub New()
        ' This call is required by the designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
        _upc = New SubmitterUserProcess()
    End Sub

    Private Sub PersonWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        _backgroundWorker_Page_Load = New BackgroundWorker
        _backgroundWorker_Page_Load.RunWorkerAsync()
    End Sub
#End Region

#Region "Control Events"
    Private Sub comboBoxDepartment_TextChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.TextChangedEventArgs)
    End Sub

    Private Sub listBoxPersons_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles listBoxPersons.SelectionChanged
        If Not _personDetail Is Nothing Then
            If _personDetail.IsDirty Then
                If _
                    MessageBox.Show("Save entries before leaving?", "Save Data", MessageBoxButton.YesNo, _
                                     MessageBoxImage.Warning) = MessageBoxResult.Yes Then
                    SavePerson()
                Else
                    If Not _personDetail.id = 0 Then
                        CancelEdit()
                    End If

                End If
            End If
        End If
        LoadSelectedPerson()
    End Sub

    Private Sub ExpanderList_Expanded(sender As Object, e As System.Windows.RoutedEventArgs) Handles ExpanderList.Expanded
        busyAnimation.Visibility = Windows.Visibility.Visible
        If _personList Is Nothing Then
            _backgroundWorker = New BackgroundWorker
            _backgroundWorker.RunWorkerAsync()
        Else
            busyAnimation.Visibility = Windows.Visibility.Collapsed
        End If
    End Sub

    Private Sub searchBox_GotFocus(sender As Object, e As RoutedEventArgs) Handles searchBox.GotFocus
        If searchBox.Text.ToUpper.Contains("SEARCH") Then
            searchBox.Text = Nothing
        End If
    End Sub

    Private Sub searchBox_TextChanged(sender As Object, e As TextChangedEventArgs) Handles searchBox.TextChanged
        If Not listBoxPersons Is Nothing Then
            Dim icview As ICollectionView = CollectionViewSource.GetDefaultView(listBoxPersons.ItemsSource)
            icview.Filter = New Predicate(Of Object)(AddressOf FilterUserTable)
        End If
    End Sub

    Private Sub buttonNew_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles buttonNew.Click
        'ExpanderList.IsExpanded = True
        If Not _personDetail Is Nothing Then
            If _personDetail.IsDirty Then
                If _
                    MessageBox.Show("There are unsaved entries. Do you want to abandon your changes?", "Refresh", _
                                     MessageBoxButton.YesNo, MessageBoxImage.Warning) = MessageBoxResult.Yes Then
                    _personDetail.ResetDirtyBit()
                    SetWindowProperties(_personDetail.IsDirty)
                    NewItemCanvas.Visibility = Windows.Visibility.Visible
                    ucNewItem.ucLabel = "New Employee ID"
                End If
            Else
                NewItemCanvas.Visibility = Windows.Visibility.Visible
                ucNewItem.ucLabel = "New Employee ID"
            End If
        Else
            NewItemCanvas.Visibility = Windows.Visibility.Visible
            ucNewItem.ucLabel = "New Employee ID"
        End If
    End Sub

    Private Sub buttonRefresh_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles buttonRefresh.Click
        If Not _personDetail Is Nothing Then
            If _personDetail.IsDirty Then
                If MessageBox.Show("There are unsaved entries. Do you really want to refresh the data?", "Refresh", _
                                     MessageBoxButton.YesNo, MessageBoxImage.Warning) = MessageBoxResult.Yes Then
                    If _personDetail.id = 0 Then
                        ClearAllControls()
                    Else
                        CancelEdit()
                    End If
                End If
            End If
        End If
    End Sub

    Private Sub buttonSave_Click(sender As Object, e As RoutedEventArgs) Handles buttonSave.Click
        If Not _personDetail Is Nothing Then
            If _personDetail.IsDirty Then
                SavePerson()
            End If
        End If
    End Sub
#End Region

#Region "Background Workers"
    ' This event handler is where the actual work is done.
    Private Sub _backgroundWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles _backgroundWorker.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        LoadPersonList()
    End Sub

    Private Sub _backgroundWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles _backgroundWorker.RunWorkerCompleted
        If (e.Error IsNot Nothing) Then
            MessageBox.Show(e.Error.Message)
        Else
            listBoxPersons.ItemsSource = _personList
            RefreshRecordCount()
            If _personList Is Nothing Then
                listBoxPersons.SelectedIndex = -1
            End If

        End If
        busyAnimation.Visibility = Windows.Visibility.Collapsed
    End Sub

    Private Sub _backgroundWorker_SaveDoWork( _
                                          ByVal sender As Object, _
                                          ByVal e As DoWorkEventArgs) _
        Handles _backgroundWorker_Save.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

        If e.Argument = "edit" Then
            _personDetail_asynch = _upc.UpdatePersonDetails(_personDetail)
        ElseIf e.Argument = "new" Then
            _personDetail_asynch = _upc.CreatePerson(_personDetail)
        End If
    End Sub

    Private Sub _backgroundWorker_SaveRunWorkerCompleted( _
                                                      ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
        Handles _backgroundWorker_Save.RunWorkerCompleted
        If (e.Error IsNot Nothing) Then
            MessageBox.Show(e.Error.Message)
        Else
            listBoxPersons.ItemsSource = _personList
            busyAnimationSaveAndDelete.Visibility = Windows.Visibility.Collapsed
            _personDetail = _personDetail_asynch
            _personDetail_asynch = Nothing
            _personDetail.ResetDirtyBit()
            SetWindowProperties(_personDetail.IsDirty)
        End If
    End Sub

    ' This event handler is where the actual work is done.
    Private Sub _backgroundWorker_Page_Load_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles _backgroundWorker_Page_Load.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        LoadDepartments()
    End Sub

    Private Sub _backgroundWorker_Page_Load_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles _backgroundWorker_Page_Load.RunWorkerCompleted
        If (e.Error IsNot Nothing) Then
            MessageBox.Show(e.Error.Message)
        Else
            comboboxDepartment.ItemsSource = _departmentList
        End If
    End Sub

    Private Sub _backgroundWorker_ChckExistingUserDoWork( _
                                         ByVal sender As Object, _
                                         ByVal e As DoWorkEventArgs) _
       Handles _backgroundWorker_CheckExisting.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        e.Result = _upc.GetPersonDetails(e.Argument)
    End Sub

    Private Sub _backgroundWorker_ChckExistingRunWorkerCompleted( _
                                                      ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
        Handles _backgroundWorker_CheckExisting.RunWorkerCompleted
        If (e.Error IsNot Nothing) Then
            MessageBox.Show(e.Error.Message)
        Else
            If Not e.Result Is Nothing Then
                ucNewItem.LabelError.Content = "Employee ID already exist."
            Else
                listBoxPersons.SelectedIndex = -1
                _personDetail = New Person()
                _personDetail.EmployeeID = ucNewItem.TextBoxNewUser.Text
                textboxCode.Text = ucNewItem.TextBoxNewUser.Text
                NewItemCanvas.Visibility = Windows.Visibility.Collapsed
                mainOverlay.Visibility = Visibility.Collapsed
                Me.Title = _personDetail.EmployeeID
                SetWindowProperties(_personDetail.IsDirty)
                Me.DataContext = _personDetail
            End If
        End If
        ucNewItem.busyAnimationNewUser_visibility = Windows.Visibility.Collapsed
    End Sub
#End Region

#Region "Support Procedures"
    Private Sub SetWindowProperties(dirty As Boolean)
        If dirty Then
            Me.Title &= If(Not Me.Title.ToUpper.Contains("UNSAVED"), " (unsaved)", "")
        Else
            Me.Title = If(Title.ToUpper.Contains("UNSAVED"), Me.Title.Substring(0, Me.Title.Length - 10), Me.Title)
        End If

        For itemIndex = 0 To oWindowList.Count - 1
            If oWindowList(itemIndex).WindowID = Me.Name Then
                oWindowList(itemIndex).WindowName = Me.Title
                oWindowList(itemIndex).WindowIsDirty = dirty
            End If
        Next
    End Sub

    Private Sub LoadPersonList()
        If _personList Is Nothing Then
            _personList = New ObservableCollection(Of Person)(_upc.GetAllPersons)
        End If
    End Sub

    Private Sub LoadDepartments()
        _departmentList = _upc.GetDepartmentList
    End Sub

    Private Sub RefreshRecordCount()
        If Not _personList Is Nothing Then
            If _personList.Count = 1 Then
                ExpanderText.Text = _personList.Count & " record found"
            Else
                ExpanderText.Text = _personList.Count & " records found"
            End If
        End If
    End Sub
    Private Sub SavePerson()
        busyAnimationSaveAndDelete.Visibility = Windows.Visibility.Visible
        Try
            _backgroundWorker_Save = New BackgroundWorker
            Dim PersonExist As Boolean = False

            If Not _personList Is Nothing Then
                If _personList.Where(Function(x) x.EmployeeID = textboxCode.Text).Count > 0 Then
                    PersonExist = True
                End If
            End If

            If PersonExist Then
                'edit
                _backgroundWorker_Save.RunWorkerAsync("edit")
                _personDetail.ResetDirtyBit()
            Else
                'new
                _personDetail = New Person
                With _personDetail
                    .EmployeeID = If(textboxCode.Text.Length = 0, Nothing, textboxCode.Text)
                    .Title = comboboxTitle.SelectedValue
                    .Designation = textboxDesignation.Text
                    .FirstName = If(textboxFirstName.Text.Length = 0, Nothing, textboxFirstName.Text)
                    .LastName = If(textboxLastName.Text.Length = 0, Nothing, textboxLastName.Text)
                    .MiddleInitial = textboxMiddleInitial.Text
                    .Gender = comboboxGender.SelectedValue
                    If textboxBirthDate.Text.Length = 0 Then
                        .DateOfBirth = Nothing
                    Else
                        .DateOfBirth = textboxBirthDate.Text
                    End If
                    .Department = comboboxDepartment.SelectedValue
                    .AdditionalInformation = textboxAdditionalInfo.Text
                    .ExtensionNumber = textboxExtensionNumber.Text
                    .EmailAddress = textboxEmailAddress.Text
                End With

                _backgroundWorker_Save.RunWorkerAsync("new")

                If Not _personList Is Nothing Then
                    'update list
                    _personList.Add(_personDetail)
                    sortData()
                    Dim ctr As Integer = 0
                    For Each item In _personList
                        If item.id = _personDetail.id Then
                            Exit For
                        End If
                        ctr += 1
                    Next
                    listBoxPersons.SelectedIndex = ctr
                End If
            End If
            _personDetail.ResetDirtyBit()
            SetWindowProperties(_personDetail.IsDirty)

            _backgroundWorker_Save.Dispose()
        Catch faultEx As FaultException
            MessageBox.Show(faultEx.Message, "Error Saving Person Details", MessageBoxButton.OK, MessageBoxImage.[Error])
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error Saving Person Details", MessageBoxButton.OK, MessageBoxImage.[Error])
        End Try
        busyAnimationSaveAndDelete.Visibility = Windows.Visibility.Collapsed
    End Sub

    Sub sortData()
        Dim ied As IEnumerable(Of Person) = From d In _personList Order By d.LastName, d.FirstName
        For Each i In ied
            _personList.Remove(i)
            _personList.Add(i)
        Next
    End Sub
    Private Sub CancelEdit()
        _personDetail.CancelEdit()
        _personDetail.ResetDirtyBit()
        SetWindowProperties(_personDetail.IsDirty)
    End Sub

    Private Sub LoadSelectedPerson()
        If listBoxPersons.SelectedIndex >= 0 Then
            _personDetail = listBoxPersons.SelectedItem
            _personDetail.ResetDirtyBit()
            HookupChangeEventHandler(_personDetail)
            mainOverlay.Visibility = Visibility.Collapsed
            Me.Title = textboxCode.Text
            _personDetail.BeginEdit()
            Me.DataContext = _personDetail
        Else
            _personDetail = Nothing
            Me.Title = "Person"
            mainOverlay.Visibility = Visibility.Visible
        End If
        If Not _personDetail Is Nothing Then
            SetWindowProperties(_personDetail.IsDirty)
        Else
            SetWindowProperties(False)
        End If
    End Sub

    Private Sub HookupChangeEventHandler(personDetail As Person)
        ' Add a PropertyChanged event handler for 
        ' the specified Customer instance:
        AddHandler _personDetail.PropertyChanged, _
            AddressOf HandlePropertyChanged
    End Sub

    Private Sub HandlePropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
        If _personDetail.IsDirty Then
            SetWindowProperties(_personDetail.IsDirty)
        End If
    End Sub


    Public Function FilterUserTable(ByVal t As Object) As Boolean
        Dim _person As Person
        _person = t
        Return _person.LastName.ToUpper.Contains(searchBox.Text.ToUpper)
    End Function

    Sub ClearAllControls()
        HelperClass.ClearCheckBox(PersonWindow)
        HelperClass.ClearComboBox(PersonWindow)
        HelperClass.ClearPasswordBox(PersonWindow)
        HelperClass.ClearTextBox(PersonWindow)
        Me.Title = "Person"
        _personDetail.ResetDirtyBit()
        SetWindowProperties(_personDetail.IsDirty)

    End Sub
    Private Sub TextBox_Error(sender As Object, e As ValidationErrorEventArgs)
        If e.Action = ValidationErrorEventAction.Added Then
            DirectCast(sender, Control).ToolTip = e.[Error].ErrorContent.ToString()
        Else
            DirectCast(sender, Control).ToolTip = ""
        End If
    End Sub
#End Region

#Region "User Control Events"

    Private Sub uc_OKButtonClicked(ByVal sender As Object, ByVal e As RoutedEventArgs) _
        Handles ucNewItem.OkButtonClicked
        ucNewItem.busyAnimationNewUser_visibility = Windows.Visibility.Visible
        _backgroundWorker_CheckExisting = New BackgroundWorker
        _backgroundWorker_CheckExisting.RunWorkerAsync(ucNewItem.TextBoxNewUser.Text)
        _backgroundWorker_CheckExisting.Dispose()
    End Sub

    Private Sub uc_CancelButtonClicked(ByVal sender As Object, ByVal e As RoutedEventArgs) _
        Handles ucNewItem.CancelButtonClicked
        NewItemCanvas.Visibility = Windows.Visibility.Collapsed
    End Sub

#End Region

End Class
